import { MapList } from "../../cfw/struct/MapList";
import { engine } from "../../engine/engine";


export class LocalData<T>{


    primaryKeyName: string = ''

    protected curData: MapList<string, T> = new MapList()

    protected updateData: MapList<string, T> = new MapList();

    protected insertData: MapList<string, T> = new MapList();

    protected deleteData: MapList<string, T> = new MapList();

    protected typeMap: { [key: string]: any } = null;

    setTypeMap(map: any) {
        this.typeMap = map;
    }
    init(list: T[]) {

        for (let index = 0; index < list.length; index++) {
            const data = list[index];
            let key = data[this.primaryKeyName]
            if (key) {
                this.curData.set(key, data)
            }
        }
    }

    get(key: string): any {
        return this.curData.get(key)
    }


    // add(data: T) {
    //     let key = data[this.primaryKeyName]
    //     if (key) {
    //         this.curData.set(key, data)
    //         this.insertKeys.set(key, key)
    //         if (this.deleteData.has(key)) {
    //             this.deleteData.delete(key)
    //         }
    //     }

    // }

    // delete(key: string) {
    //     //放入插入队列中的要删除时不用管，等于服务器中还不存在。
    //     if (this.insertKeys.has(key)) {
    //         return;
    //     }
    //     if (this.updateKeys.has(key)) {
    //         this.updateKeys.delete(key)
    //     }
    //     let data = this.curData.delete(key);
    //     if (data) {
    //         this.deleteData.set(key, data)
    //     }


    // }

    // update(key: string, valueName: string, value: any) {
    //     let data = this.curData.get(key)
    //     if (data) {
    //         data[valueName] = value;
    //         this.updateKeys.set(key, key)
    //     }
    // }
    //旧数据不存在的是新数据，放到插入队列中
    //旧数据中有，新数据也有，判断是否更新的数据
    //旧数据中存在的，新数据中没有了，删除。
    comparison(db: any[]) {
        if (db.length == 0) {
            return;
        }
        this.insertData.clear();
        this.updateData.clear();
        this.deleteData.clear()
        let oldDB = this.curData;
        this.curData = new MapList()
        this.init(db)
        for (let index = 0; index < db.length; index++) {
            const newData = db[index];
            let id = newData[this.primaryKeyName]
            if (oldDB.has(id)) {
                let oldData = oldDB.get(id)

                let isUpdate: boolean = false;
                for (const key in newData) {
                    let oldValue = oldData[key];
                    const value = newData[key];
                    if (value != undefined) {
                        if (typeof (value) == 'object') {
                            let oldValueType = typeof (oldValue)
                            if (oldValueType != 'object') {
                                engine.error('newValue type is object but oldValue type is  ', oldValueType)
                                continue;
                            }
                            let oldStr = JSON.stringify(oldValue)
                            let newStr = JSON.stringify(value)

                            if (oldStr != newStr) {
                                // LogUtils.warn(' id ', id, ' key ', key)
                                // LogUtils.warn('oldStr ', oldStr)
                                // LogUtils.warn('newStr ', newStr)
                                isUpdate = true;
                                break;
                            }
                        } else {
                            if (value != oldValue) {
                                isUpdate = true;
                                break;
                            }
                        }
                    }


                }
                if (isUpdate) {
                    // LogUtils.warn(' id ', id)
                    this.updateData.set(id, newData)
                }
            } else {//插入
                this.insertData.set(id, newData)
            }

        }
        let oldList = oldDB.getList()
        for (let index = 0; index < oldList.length; index++) {
            const oldData = oldList[index];
            let id = oldData[this.primaryKeyName]
            if (!this.curData.has(id)) {
                this.deleteData.set(id, oldData)
            }
        }
    }


    getInsertList() {
        return this.insertData.getList()
    }

    getUpdateList() {
        return this.updateData.getList()
    }

    getDeleteList() {
        return this.deleteData.getList()
    }

    getAllList(filter: any = null) {
        let list = this.curData.getList();
        if (filter) {
            let ls = [];
            for (let key in list) {
                let isMatch = true;
                if (filter) {
                    for (let k in filter) {
                        if (list[key][k] != filter[k]) {
                            isMatch = false;
                            break;
                        }
                    }
                }
                if (isMatch) {
                    ls.push(list[key]);
                }
            }
            list = ls;
        }
        let string = JSON.stringify(list);
        let all = JSON.parse(string);
        if (!all) {
            engine.warn(' list ', list)
            engine.warn(' string ', string)
        }
        return all;
    }
}